package com.zzmcc.wechat;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zzmcc.wechat.entity.Articles;
import com.zzmcc.wechat.entity.Attachment;
import com.zzmcc.wechat.bean.InMessage;
import com.zzmcc.wechat.bean.OutMessage;
import com.zzmcc.wechat.service.MessageProcessingHandler;
import com.zzmcc.wechat.oauth.Group;
import com.zzmcc.wechat.oauth.Menu;
import com.zzmcc.wechat.oauth.Message;
import com.zzmcc.wechat.oauth.User;
import com.zzmcc.wechat.util.HttpKit;
import com.zzmcc.wechat.util.Tools;
import com.zzmcc.wechat.util.XStreamFactory;
import com.thoughtworks.xstream.XStream;
import org.smart4j.framework.core.ConfigHelper;

public class WeChat {
	private static final String ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
	private static final String PAYFEEDBACK_URL = "https://api.weixin.qq.com/payfeedback/update";
	private static final String GET_MEDIA_URL= "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=";
	private static final String UPLOAD_MEDIA_URL= "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=";


    /**
     * 消息操作接口
     */
    public static final Message message = new Message();
    /**
     * 菜单操作接口
     */
    public static final Menu menu = new Menu();
    /**
     * 用户操作接口
     */
    public static final User user = new User();
    /**
     * 分组操作接口
     */
    public static final Group group = new Group();

    /**
     * 获取access_token
     * @return
     * @throws Exception
     */
    public static String getAccessToken(String appid,String secret)  {
       // String appid = ConfigHelper.getString("wechat.AppId");
       // String secret = ConfigHelper.getString("wechat.AppSecret");
        String jsonStr = HttpKit.get(ACCESSTOKEN_URL.concat("&appid=") + appid + "&secret=" + secret);
        Map<String, Object> map = JSONObject.parseObject(jsonStr);
        return map.get("access_token").toString();
    }

   /**
    * 支付反馈
    * @param openid
    * @param feedbackid
    * @param appid
    * @param secret
    */
    public static boolean payfeedback(String openid, String feedbackid,String appid,String secret)  {
        try {
            Map<String, String> map = new HashMap<String, String>();
            String accessToken = getAccessToken(appid,secret);
            map.put("access_token", accessToken);
            map.put("openid", openid);
            map.put("feedbackid", feedbackid);
            String jsonStr = HttpKit.get(PAYFEEDBACK_URL, map);
            Map<String, Object> jsonMap = JSONObject.parseObject(jsonStr);
            return "0".equals(jsonMap.get("errcode").toString());
        }catch (Exception e){

        }
        return  false;
    }


    /**
     * 根据接收到用户消息进行处理
     * @param responseInputString   微信发送过来的xml消息体
     * @return
     */
    public static String processing(String responseInputString,String handler) {
        InMessage inMessage = parsingInMessage(responseInputString);
        OutMessage oms = null;
        // 加载处理器
        String xml = "";
        try {
            MessageProcessingHandler messageProcessingHandler =InstanceFactory.getMessageProcessingHandler(handler);
            //取得消息类型
            String type = inMessage.getMsgType();
            messageProcessingHandler.allType(inMessage);
            oms = messageProcessingHandler.getOutMessage(inMessage);
            if(oms != null){
                setMsgInfo(oms, inMessage);
            }
            //调用事后处理
             messageProcessingHandler.afterProcess(inMessage,oms);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(oms != null){
            // 把发送发送对象转换为xml输出
            XStream xs = XStreamFactory.init(true);
            xs.alias("xml", oms.getClass());
            xs.alias("item", Articles.class);
            xml = xs.toXML(oms);
        }
        return xml;
    }


    /**
     * 设置发送消息体
     * @param oms
     * @param msg
     * @throws Exception
     */
    private static void setMsgInfo(OutMessage oms,InMessage msg) throws Exception {
    	if(oms != null){
    		Class<?> outMsg = oms.getClass().getSuperclass();
            Field CreateTime = outMsg.getDeclaredField("CreateTime");
            Field ToUserName = outMsg.getDeclaredField("ToUserName");
            Field FromUserName = outMsg.getDeclaredField("FromUserName");

            ToUserName.setAccessible(true);
            CreateTime.setAccessible(true);
            FromUserName.setAccessible(true);

            CreateTime.set(oms, new Date().getTime());
            ToUserName.set(oms, msg.getFromUserName());
            FromUserName.set(oms, msg.getToUserName());
    	}
    }

    /**
     *消息体转换
     * @param responseInputString
     * @return
     */
    private static InMessage parsingInMessage(String responseInputString) {
        //转换微信post过来的xml内容
        XStream xs = XStreamFactory.init(false);
        xs.ignoreUnknownElements();
        xs.alias("xml", InMessage.class);
        InMessage msg = (InMessage) xs.fromXML(responseInputString);
        return msg;
    }
    
    /**
     * 获取媒体资源
     * @param accessToken
     * @param mediaId
     * @return
     * @throws IOException
     */
    public static Attachment getMedia(String accessToken,String mediaId) throws IOException{
    	String url = GET_MEDIA_URL + accessToken + "&media_id=" + mediaId;
        return HttpKit.download(url);
    }
    
    /**
     * 上传素材文件
     * @param type
     * @param file
     * @return

     */
    @SuppressWarnings("unchecked")
	public static Map<String, Object> uploadMedia(String accessToken,String type,File file) {
        String url = UPLOAD_MEDIA_URL + accessToken +"&type="+type;
        String jsonStr = HttpKit.upload(url,file);
        return JSON.parseObject(jsonStr, Map.class);
    }

    public static void main(String args[]){

        Matcher requestPathMatcher = Pattern.compile("/oauth/(\\w+)").matcher("/oauth/a");
        if (requestPathMatcher.matches())
            System.out.print("true");
        else
            System.out.print("false");
    }
  
}